package lifo.GammaTaf.SerieParallel;

import lifo.GammaTaf.SerieParallel.SerieParallel.Sharp;
import lifo.GammaTaf.SerieParallel.SerieParallel.*;

public class SerieParallelToDotGraphe implements VisitorSerieParallel {
	private  StringBuffer graphe = new StringBuffer();
	String debut = "";
	String fin = "";
	
	static public String eval(SerieParallel exp) {
		SerieParallelToDotGraphe visitor = new SerieParallelToDotGraphe();
		visitor.graphe.append("digraph system {\n");
		exp.accepteVisiteur(visitor);

		visitor.graphe.append("debut" + " [label=\"\",shape=none]\n");
		visitor.graphe.append("debut" + " -> " + visitor.debut + "\n");
		visitor.graphe.append("fin" + " [label=\"\",shape=none]\n");
		visitor.graphe.append(visitor.fin + " -> " + "fin" + "\n");

		visitor.graphe.append("}\n");
		return visitor.graphe.toString();
	}
	
	public void visiteAction(Action action) {
		debut = "N" + action.hashCode();
		fin = "N" + action.hashCode();
		graphe.append("N" + action.hashCode() + " [label=" + action.arg +",shape=circle]\n");
	}

	public void visiteSum(Sum sum) {
		String debut = "N" + sum.hashCode();
		String fin = "F" + sum.hashCode();

		graphe.append(debut+ " [label=\"\",shape=point,width=0.02]\n");
		graphe.append(fin + " [label=\"\",shape=point,width=0.02]\n");

		for (int i=0; i<sum.arg.length; i++) {
			sum.arg[i].accepteVisiteur(this);
			graphe.append(debut + " -> " + this.debut + "\n");
			graphe.append(this.fin + " -> " + fin + "\n");
		}
		
		this.debut = debut;
		this.fin = fin;
	}

	public void visiteStar(Star star) {
		String debut = "N" + star.hashCode();
		graphe.append(debut + " [label=\"\",shape=point]\n");
		star.arg.accepteVisiteur(this);
		graphe.append(debut + " -> " + this.debut + "\n");
		graphe.append(this.fin + " -> " + debut + "\n");
		this.debut = debut;
		this.fin = debut;		
	}

	public void visiteSerie(Serie serie) {
		serie.arg[0].accepteVisiteur(this);
		String debut = this.debut;
		String fin = this.fin;
		
		for (int i=1; i<serie.arg.length; i++) {
			serie.arg[i].accepteVisiteur(this);
			graphe.append(fin + " -> " + this.debut + "\n");
			fin = this.fin;
		}
		this.debut = debut;
	}

	public void visiteParallel(Parallel parallel) {
		String debut = "N" + parallel.hashCode();
		String fin = "F" + parallel.hashCode();

		graphe.append(debut + " [label=\"\",shape=triangle]\n");
		graphe.append(fin + " [label=\"\",shape=invtriangle]\n");

		for (int i=0; i<parallel.arg.length; i++) {
			parallel.arg[i].accepteVisiteur(this);
			graphe.append(debut + " -> " + this.debut + "\n");
			graphe.append(this.fin + " -> " + fin + "\n");
		}
		
		this.debut = debut;
		this.fin = fin;
	}

	public void visiteSharp(Sharp sharp) {
		String debut = "N" + sharp.hashCode();
		String fin = "F" + sharp.hashCode();
		graphe.append(debut + " [label=\"\",shape=triangle]\n");
		graphe.append(fin + " [label=\"\",shape=invtriangle]\n");
		
		sharp.arg.accepteVisiteur(this);
		graphe.append(debut + " -> " + this.debut + "[dir=none] \n");
		graphe.append(debut + " -> " + this.debut + "[dir=none] \n");
		graphe.append(this.fin + " -> " + fin + "[dir=none] \n");
		graphe.append(this.fin + " -> " + fin + "[dir=none] \n");
		this.debut = debut;
		this.fin = fin;		
		
	}
}
